package yyy.ab.modules.security;

import lombok.RequiredArgsConstructor;
import org.springframework.security.authentication.*;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import yyy.ab.modules.security.dto.SecurityUserDto;
import yyy.ab.modules.system.mapper.SysUserRoleMapper;

import java.util.List;

/**
 * 自定义认证管理
 */
@Component
@RequiredArgsConstructor
public class AbAuthenticationProvider implements AuthenticationProvider {

    private final UserDetailsServiceImpl userService;
    private final PasswordEncoder passwordEncoder;
    private final SysUserRoleMapper userRoleMapper;

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        UsernamePasswordAuthenticationToken token = (UsernamePasswordAuthenticationToken) authentication;
        String username = token.getName();
        String credentials = (String) token.getCredentials();
        //从数据库找到的用户
        SecurityUserDto securityUser = (SecurityUserDto) userService.loadUserByUsername(username);

        if (securityUser == null) {
            throw new UsernameNotFoundException("用户名/密码无效");
        } else if (!securityUser.isEnabled()) {
            throw new DisabledException("用户已被禁用");
        } else if (!securityUser.isAccountNonExpired()) {
            throw new AccountExpiredException("账号已过期");
        } else if (!securityUser.isAccountNonLocked()) {
            throw new LockedException("账号已被锁定");
        } else if (!securityUser.isCredentialsNonExpired()) {
            throw new LockedException("凭证已过期");
        }
        //数据库用户的密码
        String password = securityUser.getPassword();
        //与authentication里面的credentials相比较
        if (!passwordEncoder.matches(credentials, password)) {
            throw new BadCredentialsException("用户名/密码无效");
        }
        //获取权限并进行写入
        List<String> permissionList = userRoleMapper.findPermissionByUserId(securityUser.getUserId());
        securityUser.writeAuthority(permissionList);
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(securityUser, securityUser.getPassword(), securityUser.getAuthorities());

        return authenticationToken;
    }

    @Override
    public boolean supports(Class<?> authentication) {
        //确保authentication能转成该类
        return authentication.equals(UsernamePasswordAuthenticationToken.class);
    }
}